package org.csy.generic.test00.demo06.myWork;

/**
 * 编写程序，使用泛型，创建一个MyArrayList的泛型类，模拟JDK中的ArrayList的实现，要求如下：
 *       1)动态扩容 - 原来长度 * 2
 *       2)add(): 添加元素
 *       3)remove(): 删除元素
 *       4)size(): 返回集合元素的实际个数
 *       5)set(): 给集合某个下标设置元素
 *       6)get(): 获取集合下标对应的元素
 *       7)isEmpty()：判断集合是否为空
 *
 *       提示：
 *       1）参考源码，方法参数根据需要自定义！
 *
 *       2）数组扩容：System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
 *           Object src : 源数组
 *           int srcPos : 从源数组的起始位置开始
 *           Object dest : 目标数组
 *           int destPos : 目标数组的开始起始位置
 *           int length  : 要copy的数组的长度
 *
 *       3）Arrays.copyOf()
 *
 * @author CSY
 * @date 2025 - 03 - 26
 */
public class MyArrayList<T> {
    /**
     * 数组的默认容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 数组
     */
    private Object[] array;

    /**
     * 默认数组 - 空
     */
    private static final Object[] DEFAULT_ARRAY = {};

    /**
     * 下标 添加数据
     */
    private int size;

    public MyArrayList() {
        array = DEFAULT_ARRAY;
    }

    /**
     * 扩容
     * @return 扩容后的数组
     */
    private Object[] grow() {
        //判断数组的长度是否为0
        if(array.length != 0){
            //数组长度不为0那么对数组进行扩容
            //实例化一个长度为旧数组长度两倍的数组
            Object[] newArray = new Object[array.length * 2];
            //使用System.arraycopy()方法进行复制 - 将旧数组从下标0开始到数组长度复制到新数组中
            //System.arraycopy(源数组,开始下标,目标数组,目标数组开始下标,要复制的长度)
            System.arraycopy(array,0,newArray,0,array.length);
            //返回新数组
            return newArray;
        }else{
            //数组长度为0将数组初始化 - 长度为默认长度
            return new Object[DEFAULT_CAPACITY];
        }
    }

    /**
     * 添加数据
     * @param t 要添加的值
     */
    public void add(T t){
        //判断实际长度是否等于数组长度 - 初始的值都为0必定进入判断
        if(size == array.length){
            array = grow();
        }
        //给数组扩容之后给数组根据实际长度进行复制
        array[size] = t;
        //每添加一个数组，实际长度就+1
        size = size + 1;
    }

    /**
     *根据指定下标删除数据
     * @param index 下标
     */
    public void remove(int index){
        //创建一个无数据数组以存储复制后的值
        Object[] newArray = new Object[array.length];
        //将要删除的数据前面的值复制到新数组中
        System.arraycopy(array,0,newArray,0,index);
        //将删除的数据后面的值继续复制到新数组中
        System.arraycopy(array,index+1,newArray,index,size - index - 1);
        //给数组重新赋值
        array = newArray;
        //实际长度-1
        size = size - 1;
    }

    /**
     * 获取长度
     * @return 长度
     */
    public Integer size(){
        //返回数组的数据数量
        return size;
    }

    /**
     * 根据下标获取数组中的值
     * @param index 下标
     * @return 指定值
     */
    public T get(Integer index){
        //返回数组指定下标的值
        return (T)array[index];
    }

    /**
     * 根据下标设置值
     * @param index 下标
     * @param t 设置的值
     */
    public void set(Integer index, T t){
        //根据指定下标给数组设置值
        array[index] = t;
    }

    /**
     * 判断集合是否为空
     * @return 布尔值
     */
    public Boolean isEmpty(){
        //size == 0 返回true ，否则返回false
        return size == 0;
    }

}
